package service;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.GregorianCalendar;
import java.util.Scanner;

import data.AppConstants;

import entity.Doctor;
import entity.Pacient;
import entity.RecordDoctor;

public class RecordDoctorService 
{

	private ConversionService conversion = new ConversionService();
	
	
	// ********************************************************************************************************** start
    // ** public methods ***	

	/**
	 * @param recordDoctors
	 * @param doctor
	 * @param date
	 * @param name
	 * @param numberCard
	 * @return recordDoctors
	 * @throws IOException 
	 */
	public ArrayList<RecordDoctor> create(
			ArrayList<RecordDoctor> recordDoctors,
			String pathToRepository,
			Doctor doctor,
			String date,
			String name,
			String numberCard) throws IOException 
	{

		RecordDoctor recordDoctor = new RecordDoctor();

		Pacient pacient = new Pacient();
		pacient.setName(name);
		pacient.setNumberCard(numberCard);

		recordDoctor.setDate(conversion.stringToDate(date));
		recordDoctor.setDoctor(doctor);
		recordDoctor.setPacient(pacient);		
		
		recordDoctors.add(recordDoctor);
		
		writeFile(pathToRepository, recordDoctors);
		
		return recordDoctors;

	}
	
	/**
	 * @param recordDoctors
	 * @param recordNumber
	 * @param doctor
	 * @param date
	 * @param name
	 * @param numberCard
	 * @return recordDoctors
	 */
	public  ArrayList<RecordDoctor>  update(
			ArrayList<RecordDoctor> recordDoctors,
			int recordNumber,
			Doctor doctor,
			String date,
			String name,
			String numberCard)
	{
		
		RecordDoctor recordDoctor = recordDoctors.get(recordNumber);
		Pacient pacient = new Pacient();
		pacient.setName(name);
		pacient.setNumberCard(numberCard);

		recordDoctor.setDoctor(doctor);
		recordDoctor.setPacient(pacient);
		recordDoctor.setDate(conversion.stringToDate(date));

		return recordDoctors;

	}
	
	/**
	 * @param recordDoctors
	 * @param recordNumber
	 * @return recordDoctors
	 */
	public ArrayList<RecordDoctor> delete(
			ArrayList<RecordDoctor> recordDoctors,
			int recordNumber)
	{

		RecordDoctor recordDoctor = recordDoctors.get(recordNumber);
		recordDoctors.remove(recordDoctor);
		
		return recordDoctors;

	}
	
	/**
	 * @param recordDoctors
	 * @throws IOException
	 */
	public void writeFile(
			String path,
			ArrayList<RecordDoctor> recordDoctors)
		throws 
			IOException 
	{

		if (!recordDoctors.isEmpty())
		{
			FileOutputStream fileOutput = new FileOutputStream(path);
			ObjectOutputStream objectOutput = new ObjectOutputStream(fileOutput);

			// write list of records
			objectOutput.writeObject(recordDoctors);
			objectOutput.flush();
			objectOutput.close();
		}
		else
		{
			System.out.println("You can not save empty report");
		}

	}

	@SuppressWarnings("unchecked")
	public ArrayList<RecordDoctor> readFile(
			String path,
			ArrayList<RecordDoctor> recordDoctor)  
	{

		System.out.println("Path:  " + path);
		try
		{
			FileInputStream fileInput = new FileInputStream(path);
			File file = new File(path);
			if(file.length() != AppConstants.EMPTY_FILE)
			{

				ObjectInputStream objectInput = new ObjectInputStream(fileInput);
				// read list of records
				recordDoctor = (ArrayList<RecordDoctor>) objectInput.readObject();
	
				fileInput.close();
				objectInput.close();
			}
		}
		catch (FileNotFoundException e) 
		{
			System.out.println("File not found. Terminate exit...");
			System.exit(0);
		} catch (IOException e) 
		{
			System.out.println("Error, file was corrupted! Terminate exit...");
			System.exit(0);
		} catch (ClassNotFoundException e) 
		{
			System.out.println("Error. Terminate exit...");
			System.exit(0);
		}

		return recordDoctor;
		
	}
	
	/**
	 * @param recordDoctors
	 * @return
	 */
	public boolean view(
			ArrayList<RecordDoctor> recordDoctors)
	{

		if (recordDoctors.isEmpty())
		{
			System.out.println("Records not found");
			return false;
		}
		
		for (int i = 0; i < recordDoctors.size(); i++)
		{
			System.out.println(i+1  + ",  date: " + conversion.dateToString(recordDoctors.get(i).getDate()) 
					+ ",  doctor: " + recordDoctors.get(i).getDoctor().getName() + 
					" - " + recordDoctors.get(i).getDoctor().getSpecialty().toString() + ",  room: " + recordDoctors.get(i).getDoctor().getNumberRoom() + ", pacient: " 
					+ recordDoctors.get(i).getPacient().getName() + ",  " + "number of card: " + recordDoctors.get(i).getPacient().getNumberCard());
		}
		
		return true;

	}
	
	/**
	 * @param recordDoctors
	 * @return
	 */
	public boolean showListPacient(
			ArrayList<RecordDoctor> recordDoctors)
	{

		if (recordDoctors.isEmpty())
		{
			System.out.println("List of recors is empty");
			return false;
		}
		
		for (int i = 0; i < recordDoctors.size(); i++)
		{
			System.out.println(i+1 + ", pacient: " 
					+ recordDoctors.get(i).getPacient().getName());
		}
		
		return true;

	}
	
	/**
	 * @param recordDoctors
	 * @param date
	 * @param name
	 * @param numberCard
	 * @return
	 */
	public boolean validation(
			ArrayList<RecordDoctor> recordDoctors,
			String date,
			String name,
			String numberCard)
	{
		
		if (conversion.stringToDate(date) == null)
		{
			return false;
		}
		
		for (RecordDoctor record : recordDoctors)
		{
			if (record.getPacient().getName().equals(name))
			{
				System.out.println("Pacient with this name already exist. Do you real want add? Y/N");
				Scanner scanner = new Scanner(System.in);
	    		String choose = scanner.next();
	    		if (choose.equals("N"))
	    		{
	    			return false;
	    		}
	    		
	    		showListPacient(recordDoctors);
			}
		}
				
		return true;
		
	}
	
	/**
	 * @param recordDoctors
	 * @return recordDoctors
	 */
	public ArrayList<RecordDoctor> sortByName(
			ArrayList<RecordDoctor> recordDoctors)
	{

		Collections.sort(recordDoctors, new Comparator<RecordDoctor>() 
		{
			public int compare(RecordDoctor record1, RecordDoctor record2) 
			{
			    return record1.getDoctor().getName().compareTo(record2.getDoctor().getName());
			}
		});
		
		return recordDoctors;

	}
	
	/**
	 * @param recordDoctors
	 * @return recordDoctors
	 */
	public ArrayList<RecordDoctor> sortBySpecialty(
			ArrayList<RecordDoctor> recordDoctors)
	{

		Collections.sort(recordDoctors, new Comparator<RecordDoctor>() 
		{
			public int compare(RecordDoctor record1, RecordDoctor record2) 
			{
				return record1.getDoctor().getSpecialty().getTitle().compareTo
					(record2.getDoctor().getSpecialty().getTitle());
			}
		});
		
		return recordDoctors;

	}
	
	/**
	 * @param recordDoctors
	 * @return recordDoctors
	 */
	public ArrayList<RecordDoctor> sortByDate(
			ArrayList<RecordDoctor> recordDoctors)
	{

		Collections.sort(recordDoctors, 
		new Comparator<RecordDoctor>() 
		{
			public int compare(RecordDoctor record1, RecordDoctor record2) 
			{
				return record1.getDate().compareTo(record2.getDate());
			}
		});
		
		return recordDoctors;

	}
	
	/**
	 * @param recordDoctors
	 * @return recordDoctors
	 */
	public ArrayList<RecordDoctor> searchByFio(
			String inputFioBySearch,
			ArrayList<RecordDoctor> recordDoctors)
	{
		
		ArrayList<RecordDoctor> resultOfSearch = new ArrayList<RecordDoctor>();

		for (RecordDoctor record : recordDoctors)
		{
			if (record.getPacient().getName().contains(inputFioBySearch) ||
					record.getDoctor().getName().contains(inputFioBySearch))
			{
				resultOfSearch.add(record);
			}
		}
		
		view(resultOfSearch);
				
		return recordDoctors;

	}
	
	/**
	 * @param recordDoctors
	 * @return recordDoctors
	 */
	public ArrayList<RecordDoctor> searchByDate(
			String inputDateBySearch,
			ArrayList<RecordDoctor> recordDoctors,
			ArrayList<RecordDoctor> subRecords)
	{

		Calendar dateBySearch = conversion.stringToDay(inputDateBySearch);
		for (RecordDoctor record : recordDoctors)
		{	
			String recordDate = record.getDate().get(GregorianCalendar.YEAR) + "." + record.getDate().get(GregorianCalendar.MONTH) +
					record.getDate().get(GregorianCalendar.DATE);
			String inputDate = dateBySearch.get(GregorianCalendar.YEAR) + "." + dateBySearch.get(GregorianCalendar.MONTH) +
				dateBySearch.get(GregorianCalendar.DATE);

			if (recordDate.equals(inputDate))
			{
				subRecords.add(record);
			}
		}
		
		view(subRecords);
				
		return recordDoctors;

	}
	
	// ********************************************************************************************************** end

}
